package com.tanhua.dubbo.api;

import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.dubbo.util.IdGenerator;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@Service
public class PublishApiImpl implements PublishApi {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdGenerator idGenerator;

    /**
     * 查询给targetUserId 推荐的动态列表
     *  1. 查询推荐表-给用户推荐了哪些publishId
     *  2. 查询publish列表返回
     */
    @Override
    public PageResult findRecommendPublish(int page, int pagesize, Long targetUserId) {
        //1. 查询推荐表
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(targetUserId));
        query.with(PageRequest.of(page - 1, pagesize));
        query.with(Sort.by(Sort.Order.desc("created")));
        List<RecommendQuanZi> list = mongoTemplate.find(query, RecommendQuanZi.class);
        long count = mongoTemplate.count(query, RecommendQuanZi.class);
        //2. 查询publish表
        List<Publish> publishList = new ArrayList<>();
        for (RecommendQuanZi recommendQuanZi : list) {
            Publish publish = mongoTemplate.findById(recommendQuanZi.getPublishId(), Publish.class);
            publishList.add(publish);
        }
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult((int) count, pagesize, pages, page, publishList);
    }

    /**
     * 发布动态
     *  1. 将动态保存到publish表
     *  2. 获取publishId保存到album表
     *  3. 将动态保存到好友时间线表
     */
    @Override
    public String save(Publish publish) {
        //1. 将动态保存到publish表
        publish.setId(ObjectId.get());
        publish.setPid(idGenerator.nextId("publish"));
        publish.setCreated(System.currentTimeMillis());
        publish.setLikeCount(0);
        publish.setLoveCount(0);
        publish.setCommentCount(0);
        mongoTemplate.insert(publish);

        //2. 获取publishId保存到album表
        Album album = new Album();
        album.setCreated(System.currentTimeMillis());
        album.setPublishId(publish.getId());
        mongoTemplate.insert(album,"quanzi_album_"+publish.getUserId());

        //3. 将动态保存到好友时间线表
        //3.1 获取好友列表
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(publish.getUserId()));
        List<Friend> list = mongoTemplate.find(query, Friend.class);
        for (Friend friend : list) {
            //3.2 将动态保存到好友的时间线
            TimeLine timeLine = new TimeLine();
            timeLine.setPublishId(publish.getId());
            timeLine.setUserId(publish.getUserId());
            timeLine.setCreated(System.currentTimeMillis());
            mongoTemplate.insert(timeLine, "quanzi_time_line_" + friend.getFriendId());
        }
        return publish.getId().toHexString();
    }

    /**
     * 好友动态查询
     *  1. 根据自己时间线查询好友动态id
     *  2. 根据动态id查询publish
     */
    @Override
    public PageResult findFriendPublish(int page, int pagesize, Long userId) {
        Query query = new Query();
        query.with(Sort.by(Sort.Order.desc("created")));
        query.with(PageRequest.of(page - 1, pagesize));
        List<TimeLine> list = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + userId);
        long count = mongoTemplate.count(query, TimeLine.class, "quanzi_time_line_" + userId);
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        List<Publish> publishList = new ArrayList<>();
        if (list.size() > 0) {
            for (TimeLine timeLine : list) {
                Publish publish = mongoTemplate.findById(timeLine.getPublishId(), Publish.class);
                publishList.add(publish);
            }
        }
        return new PageResult((int) count, pagesize, pages, page, publishList);
    }

    /**
     * 查询用户动态
     *  1. 查询quanzi_album_userId表
     *  2. 查询publish表
     */
    @Override
    public PageResult findUserPublish(int page, int pagesize, Long userId) {
        Query query = new Query();
        query.with(PageRequest.of(page - 1, pagesize));
        query.with(Sort.by(Sort.Order.desc("created")));
        List<Album> list = mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);

        long count = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);

        List<Publish> publishList = new ArrayList<>();
        for (Album album : list) {
            Publish publish = mongoTemplate.findById(album.getPublishId(), Publish.class);
            publishList.add(publish);
        }

        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult((int) count, pagesize, pages, page, publishList);
    }

    @Override
    public Publish findById(ObjectId publishId) {
        return mongoTemplate.findById(publishId, Publish.class);
    }

    @Override
    public PageResult findPublishList(Integer page, Integer pagesize, Long userId, Integer state) {
        Query query = new Query();
        if (userId != null) {
            query.addCriteria(Criteria.where("userId").is(userId));
        }
        if (state != null) {
            query.addCriteria(Criteria.where("state").is(state));
        }
        query.with(Sort.by(Sort.Order.desc("created")));
        query.with(PageRequest.of(page - 1, pagesize));
        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        long count = mongoTemplate.count(query, Publish.class);

        int pages = (int) Math.ceil(count * 1.0 / pagesize);

        return new PageResult((int)count, pagesize, pages, page, publishList);
    }

    @Override
    public void updateState(Publish publish) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(publish.getId()));
        Update update = new Update();
        update.set("state", publish.getState());
        mongoTemplate.updateFirst(query, update, Publish.class);
    }

    @Override
    public List<Publish> findListByPids(List<Long> pidList) {
        return mongoTemplate.find(Query.query(Criteria.where("pid").in(pidList)), Publish.class);
    }
    @Override
    public void dynamicPass(String[] ids) {
        for (String id : ids) {
            Query query = new Query();
            query.addCriteria(Criteria.where("id").is(id));
            Update update = new Update();
            //人工审核通过
            update.set("state",1);
            mongoTemplate.updateFirst(query, update, Publish.class);
        }
    }

    @Override
    public void dynamicRefusal(String[] ids) {
        for (String id : ids) {
            Query query = new Query();
            query.addCriteria(Criteria.where("id").is(id));
            Update update = new Update();
            //审核驳回
            update.set("state",2);
            mongoTemplate.updateFirst(query, update, Publish.class);
        }
    }
}
